#include "Shader.h"

//Shader::Shader()
//{
//	ProgramObject = 0;
//	m_vertexShader = 0;
//	m_fragmentShader = 0;
//}
//
//Shader::Shader(FWuint count, char* path, char* names)
//{
//	Position = -1;
//	Color = -1;
//	Coordinate = -1;
//	Normal = -1;
//	BiNormal = -1;
//	Tangent = -1;
//	MatrixLocal = -1;
//	MatrixWVP = -1;
//	CubeSampler = -1;
//	for (int i = 0; i < 10; i++)
//		Samplers[i] = -1;
//
//	ProgramObject = 0;
//	m_vertexShader = 0;
//	m_fragmentShader = 0;
//
//	m_fileCount = count;
//	m_filesPath = path;
//	m_fileNames = names;
//}
//
//FWint Shader::Init()
//{
//	//Khong du du lieu de khoi tao shader
//	if (m_fileCount != 2)
//		return -1;
//
//	char **files = new char*[m_fileCount];
//	char* temp = strtok(_strdup(m_fileNames),";");
//	int i = 0;
//	while (temp != NULL)
//	{
//		files[i] = temp;
//		temp = strtok(NULL, ";");
//		i++;
//	}
//
//	//Tao vertex shader
//	std::string file = BASE_SRC_PATH + std::string(m_filesPath) + std::string(files[0]);
//	char* src = ShaderHelper::ReadShader(file.c_str());
//	m_vertexShader = ShaderHelper::LoadShader(GL_VERTEX_SHADER, src);
//	SAFE_DEL_ARRAY(src);
//	//Khong khoi tao duoc shader
//	if (m_vertexShader == 0)
//		return -2;
//
//	//Tao fragment shader
//	file = BASE_SRC_PATH + std::string(m_filesPath) + std::string(files[1]);
//	src = ShaderHelper::ReadShader(file.c_str());
//	m_fragmentShader = ShaderHelper::LoadShader(GL_FRAGMENT_SHADER, src);
//	SAFE_DEL_ARRAY(src);
//	//Khong khoi tao duoc shader
//	if (m_fragmentShader == 0)
//	{
//		glDeleteShader(m_vertexShader);
//		return -2;
//	}
//
//	SAFE_DEL_ARRAY(files);
//
//	ProgramObject = ShaderHelper::LoadProgram(m_vertexShader, m_fragmentShader);
//	if (ProgramObject == 0)
//	{
//		glDeleteShader(m_vertexShader);
//		glDeleteShader(m_fragmentShader);
//		return -2;
//	}
//
//	Position = glGetAttribLocation(ProgramObject, "a_PosL");
//	Color = glGetAttribLocation(ProgramObject, "a_ColorL");
//	Coordinate = glGetAttribLocation(ProgramObject, "a_UV");
//	Normal = glGetAttribLocation(ProgramObject, "a_Normal");
//	BiNormal = glGetAttribLocation(ProgramObject, "a_BiNormal");
//	Tangent = glGetAttribLocation(ProgramObject, "a_TGT");
//	
//	MatrixLocal = glGetUniformLocation(ProgramObject, "u_MatrixL");
//	MatrixWVP = glGetUniformLocation(ProgramObject, "u_MatrixWVP");
//	
//	CubeSampler = glGetUniformLocation(ProgramObject, "u_SamplerCube");
//	Samplers[0] = glGetUniformLocation(ProgramObject, "u_Sampler0");
//	Samplers[1] = glGetUniformLocation(ProgramObject, "u_Sampler1");
//	Samplers[2] = glGetUniformLocation(ProgramObject, "u_Sampler2");
//	Samplers[3] = glGetUniformLocation(ProgramObject, "u_Sampler3");
//	Samplers[4] = glGetUniformLocation(ProgramObject, "u_Sampler4");
//	Samplers[5] = glGetUniformLocation(ProgramObject, "u_Sampler5");
//	Samplers[6] = glGetUniformLocation(ProgramObject, "u_Sampler6");
//	Samplers[7] = glGetUniformLocation(ProgramObject, "s_SamplerNormal");
//	Samplers[8] = glGetUniformLocation(ProgramObject, "s_SamplerLighting");
//	Samplers[9] = glGetUniformLocation(ProgramObject, "s_SamplerShadow");
//
//	return 0;
//}
//
//void Shader::Destroy()
//{
//	glDeleteShader(m_vertexShader);
//	glDeleteShader(m_fragmentShader);
//	glDeleteProgram(ProgramObject);
//}
//
//FWuint Shader::FindAttribute(const char* name){
//	return glGetAttribLocation(ProgramObject, name);
//}
//
//FWuint Shader::FindUniform(const char* name){
//	return glGetUniformLocation(ProgramObject, name);
//}
//
////void Shader::Load()
////{
////	Position = glGetAttribLocation(ProgramObject, "a_PosL");
////	Color = glGetAttribLocation(ProgramObject, "a_ColorL");
////	Coordinate = glGetAttribLocation(ProgramObject, "a_UV");
////	Normal = glGetAttribLocation(ProgramObject, "a_Normal");
////	BiNormal = glGetAttribLocation(ProgramObject, "a_BiNormal");
////	Tangent = glGetAttribLocation(ProgramObject, "a_TGT");
////
////	MatrixLocal = glGetUniformLocation(ProgramObject, "u_MatrixL");
////	MatrixWVP = glGetUniformLocation(ProgramObject, "u_MatrixWVP");
////
////	CubeSampler = glGetUniformLocation(ProgramObject, "u_SamplerCube");
////	Samplers[0] = glGetUniformLocation(ProgramObject, "u_Sampler0");
////	Samplers[1] = glGetUniformLocation(ProgramObject, "u_Sampler1");
////	Samplers[2] = glGetUniformLocation(ProgramObject, "u_Sampler2");
////	Samplers[3] = glGetUniformLocation(ProgramObject, "u_Sampler3");
////	Samplers[4] = glGetUniformLocation(ProgramObject, "u_Sampler4");
////	Samplers[5] = glGetUniformLocation(ProgramObject, "u_Sampler5");
////	Samplers[6] = glGetUniformLocation(ProgramObject, "u_Sampler6");
////	Samplers[7] = glGetUniformLocation(ProgramObject, "s_SamplerNormal");
////	Samplers[8] = glGetUniformLocation(ProgramObject, "s_SamplerLighting");
////	Samplers[9] = glGetUniformLocation(ProgramObject, "s_SamplerShadow");
////
////}

//=================================//
Shader::Shader()
{
	m_filePath = NULL;
	m_fileVertex = NULL;
	m_fileFragment = NULL;

	ProgramObject = 0;
	m_vertexShader = 0;
	m_fragmentShader = 0;
}

Shader::Shader(char* path, char* vs, char* fs)
{
	Position = -1;
	Coordinate = -1;
	Normal = -1;
	BiNormal = -1;
	Tangent = -1;
	MatrixLocal = -1;
	MatrixWVP = -1;
	CubeSampler = -1;
	for (int i = 0; i < 10; i++)
		Samplers[i] = -1;

	ProgramObject = 0;
	m_vertexShader = 0;
	m_fragmentShader = 0;

	m_filePath = new char[strlen(path) + 1];
	strcpy(m_filePath, path);
	m_fileVertex = new char[strlen(vs) + 1];
	strcpy(m_fileVertex, vs);
	m_fileFragment = new char[strlen(fs) + 1];
	strcpy(m_fileFragment, fs);
}

FWint Shader::Init()
{
	if (m_fileVertex == NULL || m_fileFragment == NULL)
		return FW_ERR_NO_DATA;

	//Tao vertex shader
	std::string file = BASE_SRC_PATH + std::string(m_filePath) + std::string(m_fileVertex);
	char* src = ShaderHelper::ReadShader(file.c_str());
	m_vertexShader = ShaderHelper::LoadShader(GL_VERTEX_SHADER, src);
	SAFE_DEL_ARRAY(src);
	//Khong khoi tao duoc shader
	if (m_vertexShader == 0)
		return -2;

	//Tao fragment shader
	file = BASE_SRC_PATH + std::string(m_filePath) + std::string(m_fileFragment);
	src = ShaderHelper::ReadShader(file.c_str());
	m_fragmentShader = ShaderHelper::LoadShader(GL_FRAGMENT_SHADER, src);
	SAFE_DEL_ARRAY(src);
	//Khong khoi tao duoc shader
	if (m_fragmentShader == 0)
	{
		glDeleteShader(m_vertexShader);
		return -2;
	}

	ProgramObject = ShaderHelper::LoadProgram(m_vertexShader, m_fragmentShader);
	if (ProgramObject == 0)
	{
		glDeleteShader(m_vertexShader);
		glDeleteShader(m_fragmentShader);
		return -2;
	}

	Position = glGetAttribLocation(ProgramObject, "a_PosL");
	Coordinate = glGetAttribLocation(ProgramObject, "a_UV");
	Normal = glGetAttribLocation(ProgramObject, "a_Normal");
	BiNormal = glGetAttribLocation(ProgramObject, "a_BiNormal");
	Tangent = glGetAttribLocation(ProgramObject, "a_TGT");

	MatrixLocal = glGetUniformLocation(ProgramObject, "u_MatrixL");
	MatrixWVP = glGetUniformLocation(ProgramObject, "u_MatrixWVP");

	CubeSampler = glGetUniformLocation(ProgramObject, "u_SamplerCube");
	Samplers[0] = glGetUniformLocation(ProgramObject, "u_Sampler0");
	Samplers[1] = glGetUniformLocation(ProgramObject, "u_Sampler1");
	Samplers[2] = glGetUniformLocation(ProgramObject, "u_Sampler2");
	Samplers[3] = glGetUniformLocation(ProgramObject, "u_Sampler3");
	Samplers[4] = glGetUniformLocation(ProgramObject, "u_Sampler4");
	Samplers[5] = glGetUniformLocation(ProgramObject, "u_Sampler5");
	Samplers[6] = glGetUniformLocation(ProgramObject, "u_Sampler6");
	Samplers[7] = glGetUniformLocation(ProgramObject, "s_SamplerNormal");
	Samplers[8] = glGetUniformLocation(ProgramObject, "s_SamplerLighting");
	Samplers[9] = glGetUniformLocation(ProgramObject, "s_SamplerShadow");

	return 0;
}

void Shader::Destroy()
{
	glDeleteShader(m_vertexShader);
	glDeleteShader(m_fragmentShader);
	glDeleteProgram(ProgramObject);

	SAFE_DEL_ARRAY(m_filePath);
	SAFE_DEL_ARRAY(m_fileVertex);
	SAFE_DEL_ARRAY(m_fileFragment);
}

FWuint Shader::FindAttribute(const char* name){
	return glGetAttribLocation(ProgramObject, name);
}

FWuint Shader::FindUniform(const char* name){
	return glGetUniformLocation(ProgramObject, name);
}